home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianVisBalls.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  17KB  |  644 lines

  1. /*ScianVisBalls.c
  2.   Sept 23, 1992
  3.   Eric Pepke
  4.   Balls visualization object in SciAn*/
  5.  
  6. #include "Scian.h"
  7. #include "ScianTypes.h"
  8. #include "ScianArrays.h"
  9. #include "ScianWindows.h"
  10. #include "ScianTextBoxes.h"
  11. #include "ScianButtons.h"
  12. #include "ScianTitleBoxes.h"
  13. #include "ScianObjWindows.h"
  14. #include "ScianIcons.h"
  15. #include "ScianColors.h"
  16. #include "ScianControls.h"
  17. #include "ScianLists.h"
  18. #include "ScianSliders.h"
  19. #include "ScianIDs.h"
  20. #include "ScianDatasets.h"
  21. #include "ScianPictures.h"
  22. #include "ScianDialogs.h"
  23. #include "ScianErrors.h"
  24. #include "ScianComplexControls.h"
  25. #include "ScianMethods.h"
  26. #include "ScianStyle.h"
  27. #include "ScianVisObjects.h"
  28. #include "ScianVisBalls.h"
  29. #include "ScianDraw.h"
  30. #include "ScianTemplates.h"
  31. #include "ScianTemplateHelper.h"
  32. #include "ScianSymbols.h"
  33.  
  34. ObjPtr visBalls;    /*Class for ball cloud*/
  35.  
  36. /*Ball style flags*/
  37. #define BS_JACKS    2
  38. #define BS_CUBES    4
  39. #define BS_OCTOHEDRA    8
  40. #define BS_SPHERES    16
  41.  
  42. /*Just in case I screw up*/
  43. #undef DEFORMOBJ
  44. #undef DEFCONSTANT
  45. #undef DEFOFFSET
  46. #undef DEFFACTOR
  47. #undef DEFORMSWITCH
  48. #define visDeformed HAHAHAHA
  49.  
  50. static ObjPtr AddBallsControls(object, panelContents)
  51. ObjPtr object, panelContents;
  52. /*Adds controls to a balls object*/
  53. {
  54.     ObjPtr titleBox, checkBox;
  55.     ObjPtr var;
  56.     int style;
  57.  
  58.     /*Get the style variable*/
  59.     var = GetIntVar("AddBallsControls", object, POINTSTYLE);
  60.     if (!var)
  61.     {
  62.     var = NewInt(BS_OCTOHEDRA);
  63.     SetVar(object, POINTSTYLE, var);
  64.     style = GetInt(var);
  65.     }
  66.  
  67.     /*Make the title box*/
  68.     titleBox = TemplateTitleBox(BallsTemplate, "Style");
  69.     PrefixList(panelContents, titleBox);
  70.     SetVar(titleBox, PARENT, panelContents);
  71.  
  72.     /*Make the check boxes*/
  73.  
  74.     checkBox = TemplateCheckBox(BallsTemplate, "Jacks", style & BS_JACKS ? 1 : 0);
  75.     PrefixList(panelContents, checkBox);
  76.     SetVar(checkBox, PARENT, panelContents);
  77.     AssocFlagControlWithVar(checkBox, object, POINTSTYLE, BS_JACKS);
  78.     SetVar(checkBox, HELPSTRING,
  79.     NewString("When this box is on, jacks are drawn at all the nodes \
  80. in the visualization.  The size of the jacks can be controlled from within \
  81. the Size control panel."));
  82.  
  83.     checkBox = TemplateCheckBox(BallsTemplate, "Cubes", style & BS_CUBES ? 1 : 0);
  84.     PrefixList(panelContents, checkBox);
  85.     SetVar(checkBox, PARENT, panelContents);
  86.     AssocFlagControlWithVar(checkBox, object, POINTSTYLE, BS_CUBES);
  87.     SetVar(checkBox, HELPSTRING,
  88.     NewString("When this box is on, cubes are drawn at all the nodes \
  89. in the visualization.  The size of the cubes can be controlled from within \
  90. the Size control panel."));
  91.  
  92.     checkBox = TemplateCheckBox(BallsTemplate, "Octohedra", style & BS_OCTOHEDRA ? 1 : 0);
  93.     PrefixList(panelContents, checkBox);
  94.     SetVar(checkBox, PARENT, panelContents);
  95.     AssocFlagControlWithVar(checkBox, object, POINTSTYLE, BS_OCTOHEDRA);
  96.     SetVar(checkBox, HELPSTRING,
  97.     NewString("When this box is on, octohedra are drawn at all the nodes \
  98. in the visualization.  The size of the octohedra can be controlled from within \
  99. the Size control panel."));
  100.  
  101.     checkBox = TemplateCheckBox(BallsTemplate, "Spheres", style & BS_SPHERES ? 1 : 0);
  102.     PrefixList(panelContents, checkBox);
  103.     SetVar(checkBox, PARENT, panelContents);
  104.     AssocFlagControlWithVar(checkBox, object, POINTSTYLE, BS_SPHERES);
  105.     SetVar(checkBox, HELPSTRING,
  106.     NewString("When this box is on, spheres are drawn at all the nodes \
  107. in the visualization.  The size of the spheres can be controlled from within \
  108. the Size control panel.  The resolution of the spheres can be controlled from \
  109. within the Geometry control panel."));
  110.  
  111.     return ObjTrue;
  112. }
  113.  
  114. typedef VertexPtr SixVertices[6];
  115. typedef VertexPtr CubeVertices[2][2][2];
  116.  
  117. static ObjPtr MakeBallsSurface(balls)
  118. ObjPtr balls;
  119. /*Makes the surface of a balls object*/
  120. {
  121.     ObjPtr ballsData;
  122.     ObjPtr surface;
  123.     ObjPtr var;
  124.     int style;            /*Style of balls to make*/
  125.     var = GetVar(balls, POINTSTYLE);
  126.     if (var)
  127.     {
  128.     style = GetInt(var);
  129.     }
  130.     else
  131.     {
  132.     style = BS_OCTOHEDRA;
  133.     }
  134.  
  135.     surface = NewPicture();
  136.  
  137.     /*Get the main dataset*/
  138.     MakeVar(balls, MAINDATASET);
  139.     ballsData = GetVar(balls, MAINDATASET);
  140.  
  141.     if (ballsData && style)
  142.     {
  143.     /*There is some data.  Put stuff on the surface*/
  144.     int nTraversalDims;        /*Number of dimensions to traverse*/
  145.     int whichDim;            /*Dimension counter*/
  146.     long *traversalDims = 0;    /*Dimensions of the dataset to traverse*/
  147.     long *index = 0;        /*Counting index*/
  148.     long nNodes;            /*# Total nodes in the dataset*/
  149.     VertexPtr *centerVertices = 0;    /*Center vertices*/
  150.     SixVertices *faceVertices = 0;    /*Face-centered vertices*/
  151.     CubeVertices *cornerVertices = 0;  /*Corner vertices*/
  152.     long nVertices;            /*Number of vertices so far*/
  153.     int nComponents;        /*# components of data form*/
  154.     real size = 1.0;        /*Size of the object*/
  155.     VertexPtr tv;            /*Temporary vertex*/
  156.     long k;                /*Counter*/
  157.     real x, y, z;
  158.     PicItemPtr item;
  159.     int sphereSub;            /*# subdivisions in field*/
  160.     ObjPtr sizeObj;            /*Object to size by*/
  161.     real offset, factor;        /*Offset and factor for deformation*/
  162.     Bool sameForm;            /*True iff forms are the same*/
  163.  
  164.     var = GetIntVar("MakeBallsSurface", balls, SPHERESUBDIV);
  165.     if (var)
  166.     {
  167.         sphereSub = GetInt(var);
  168.     }
  169.     else
  170.     {
  171.         sphereSub = 2;
  172.     }
  173.  
  174.     /*See if we need to size by an object*/
  175.     size = 1.0;
  176.     sizeObj = NULLOBJ;
  177.     if (style & (BS_JACKS | BS_CUBES | BS_OCTOHEDRA | BS_SPHERES))
  178.     {
  179.         if (GetPredicate(balls, SIZESWITCH))
  180.         {
  181.         MakeVar(balls, SIZEOBJ);
  182.         sizeObj = GetVar(balls, SIZEOBJ);
  183.         }
  184.     }
  185.  
  186.     MakeVar(balls, SIZEFACTOR);
  187.     var = GetRealVar("MakeBallsSurface", balls, SIZEFACTOR);
  188.     if (var)
  189.     {
  190.         factor = GetReal(var);
  191.     }
  192.     else
  193.     {
  194.         factor = 1.0;
  195.     }
  196.  
  197.     MakeVar(balls, SIZEOFFSET);
  198.     var = GetRealVar("MakeBallsSurface", balls, SIZEOFFSET);
  199.     if (var)
  200.     {
  201.         offset = GetReal(var);
  202.     }
  203.     else
  204.     {
  205.         offset = 0.0;
  206.     }
  207.  
  208.     SetCurForm(FORMFIELD, ballsData);
  209.     nComponents = GetNComponents(FORMFIELD);
  210.  
  211.     if (sizeObj)
  212.     {
  213.         SetCurField(FIELD1, sizeObj);
  214.         SetCurForm(FIELD2, sizeObj);
  215.         if (IdenticalFields(FORMFIELD, FIELD2))
  216.         {
  217.         sameForm = true;
  218.         }
  219.         else
  220.         {
  221.         sameForm = false;
  222.         }
  223.     }
  224.     else
  225.     {
  226.         MakeVar(balls, SIZECONSTANT);
  227.         var = GetRealVar("MakeBallsSurface", balls, SIZECONSTANT);
  228.         if (var)
  229.         {
  230.         size = GetReal(var) * factor + offset;
  231.         }
  232.         else
  233.         {
  234.         size = factor + offset;
  235.         }
  236.     }
  237.  
  238.     /*Get the information on traversing the dataset*/
  239.     nTraversalDims = CountTraversalDims(FORMFIELD);
  240.     if (nTraversalDims)
  241.     {
  242.         traversalDims = (long *) Alloc(sizeof(long) * nTraversalDims);
  243.         index = (long *) Alloc(sizeof(long) * nTraversalDims);
  244.     }
  245.     else
  246.     {
  247.         index = (long *) Alloc(sizeof(long));
  248.     }
  249.     GetTraversalDims(FORMFIELD, traversalDims);
  250.  
  251.     /*Calculate the number of nodes*/
  252.     nNodes = 1;
  253.     for (whichDim = 0; whichDim < nTraversalDims; ++whichDim)
  254.     {
  255.         if (traversalDims[whichDim] > 0)
  256.         {
  257.         nNodes *= traversalDims[whichDim];
  258.         }
  259.     }
  260.  
  261.     /*Make as many vertices as we might need nodes*/
  262.     centerVertices = (VertexPtr *) Alloc(sizeof(VertexPtr) * nNodes);
  263.     if (!centerVertices)
  264.     {
  265.         OMErr();
  266.         return ObjFalse;
  267.     }
  268.     if ((style & BS_JACKS) || (style & BS_OCTOHEDRA))
  269.     {
  270.         faceVertices = (SixVertices *) Alloc(sizeof(SixVertices) * nNodes);
  271.         if (!faceVertices)
  272.         {
  273.         OMErr();
  274.         SAFEFREE(centerVertices);
  275.         return ObjFalse;
  276.         }
  277.     }
  278.     if ((style & BS_CUBES))
  279.     {
  280.         cornerVertices = (CubeVertices *) Alloc(sizeof(CubeVertices) * nNodes);
  281.         if (!cornerVertices)
  282.         {
  283.         OMErr();
  284.         SAFEFREE(centerVertices);
  285.         SAFEFREE(cornerVertices);
  286.         return ObjFalse;
  287.         }
  288.     }
  289.     
  290.     /*Fill the vertices*/
  291.  
  292.     nVertices = 0;
  293.  
  294.     /*Zero the index*/
  295.     for (whichDim = 0; whichDim < nTraversalDims; ++whichDim)
  296.     {
  297.         index[whichDim] = 0;
  298.     }
  299.  
  300.     /*Traverse all the balls*/
  301.     do
  302.     {
  303.         /*Sample the location at a ball*/
  304.         x = (0 >= nComponents) ? 0.0 : SelectFieldComponent(FORMFIELD, 0, index);
  305.         y = (1 >= nComponents) ? 0.0 : SelectFieldComponent(FORMFIELD, 1, index);
  306.         z = (2 >= nComponents) ? 0.0 : SelectFieldComponent(FORMFIELD, 2, index);
  307.         if (x == missingData) x = 0.0;
  308.         if (y == missingData) y = 0.0;
  309.         if (z == missingData) z = 0.0;
  310.  
  311.         /*If there's a size object, make a new size*/
  312.         if (sizeObj)
  313.         {
  314.         if (sameForm)
  315.         {
  316.             size = SelectFieldScalar(FIELD1, index) * factor + offset;
  317.         }
  318.         else
  319.         {
  320.             real sample;
  321.             real position[3];
  322.             position[0] = x; position[1] = y; position[2] = z;
  323.             sample = SampleSpatScalar(FIELD1, FIELD2,
  324.                     3, position, true);
  325.             size = sample * factor + offset;
  326.         }
  327.         }
  328.  
  329.         /*Make a vertex*/
  330.         if (nVertices)
  331.         {
  332.         centerVertices[nVertices] = NewVertex(surface, VF_NEXTCANON);
  333.         }
  334.         else
  335.         {
  336.         centerVertices[nVertices] = NewVertex(surface, VF_FIRSTCANON);        
  337.         }
  338.  
  339.         /*Make some center vertices*/
  340.         centerVertices[nVertices] -> position[0] = x;
  341.         centerVertices[nVertices] -> position[1] = y;
  342.         centerVertices[nVertices] -> position[2] = z;
  343.         centerVertices[nVertices] -> normal[0] = 0.0;
  344.         centerVertices[nVertices] -> normal[0] = 0.0;
  345.         centerVertices[nVertices] -> normal[0] = 1.0;
  346.         centerVertices[nVertices] -> colorIndex = 2;
  347.  
  348.         /*Put in the sphere if need be*/
  349.         if ((style & BS_SPHERES))
  350.         {
  351.         ConvertSphereOntoPicture(surface, centerVertices[nVertices], size,
  352.             VF_SAMEPLACE, sphereSub);
  353.         }
  354.  
  355.         if ((style & BS_JACKS) || (style & BS_OCTOHEDRA))
  356.         {
  357.         /*Make some face centered vertices*/
  358.         faceVertices[nVertices][0] = tv = NewVertex(surface, VF_SAMEPLACE);
  359.         tv -> position[0] = x - size;
  360.         tv -> position[1] = y;
  361.         tv -> position[2] = z;
  362.         tv -> normal[0] = -1.0;
  363.         tv -> normal[1] = 0.0;
  364.         tv -> normal[2] = 0.0;
  365.  
  366.         faceVertices[nVertices][1] = tv = NewVertex(surface, VF_SAMEPLACE);
  367.         tv -> position[0] = x + size;
  368.         tv -> position[1] = y;
  369.         tv -> position[2] = z;
  370.         tv -> normal[0] = 1.0;
  371.         tv -> normal[1] = 0.0;
  372.         tv -> normal[2] = 0.0;
  373.  
  374.         faceVertices[nVertices][2] = tv = NewVertex(surface, VF_SAMEPLACE);
  375.         tv -> position[0] = x;
  376.         tv -> position[1] = y - size;
  377.         tv -> position[2] = z;
  378.         tv -> normal[0] = 0.0;
  379.         tv -> normal[1] = -1.0;
  380.         tv -> normal[2] = 0.0;
  381.  
  382.         faceVertices[nVertices][3] = tv = NewVertex(surface, VF_SAMEPLACE);
  383.         tv -> position[0] = x;
  384.         tv -> position[1] = y + size;
  385.         tv -> position[2] = z;
  386.         tv -> normal[0] = 0.0;
  387.         tv -> normal[1] = 1.0;
  388.         tv -> normal[2] = 0.0;
  389.  
  390.         faceVertices[nVertices][4] = tv = NewVertex(surface, VF_SAMEPLACE);
  391.         tv -> position[0] = x;
  392.         tv -> position[1] = y;
  393.         tv -> position[2] = z - size;
  394.         tv -> normal[0] = 0.0;
  395.         tv -> normal[1] = 0.0;
  396.         tv -> normal[2] = -1.0;
  397.  
  398.         faceVertices[nVertices][5] = tv = NewVertex(surface, VF_SAMEPLACE);
  399.         tv -> position[0] = x;
  400.         tv -> position[1] = y;
  401.         tv -> position[2] = z + size;
  402.         tv -> normal[0] = 0.0;
  403.         tv -> normal[1] = 0.0;
  404.         tv -> normal[2] = 1.0;
  405.         }
  406.  
  407. #undef MAKECORNERVERTEX
  408. #define MAKECORNERVERTEX(a, b, c)                    \
  409.         cornerVertices[nVertices][a][b][c] = tv =        \
  410.             NewVertex(surface, VF_SAMEPLACE);        \
  411.         tv -> position[0] = a ? x + size : x - size;        \
  412.         tv -> position[1] = b ? y + size : y - size;        \
  413.         tv -> position[2] = c ? z + size : z - size;        \
  414.         tv -> normal[0] = a ? SQ33 : -SQ33;            \
  415.         tv -> normal[1] = b ? SQ33 : -SQ33;            \
  416.         tv -> normal[2] = c ? SQ33 : -SQ33;
  417.  
  418.         if ((style & BS_CUBES))
  419.         {
  420.         /*Make some corner vertices*/
  421.         MAKECORNERVERTEX(0, 0, 0);
  422.         MAKECORNERVERTEX(0, 0, 1);
  423.         MAKECORNERVERTEX(0, 1, 0);
  424.         MAKECORNERVERTEX(0, 1, 1);
  425.         MAKECORNERVERTEX(1, 0, 0);
  426.         MAKECORNERVERTEX(1, 0, 1);
  427.         MAKECORNERVERTEX(1, 1, 0);
  428.         MAKECORNERVERTEX(1, 1, 1);
  429.         }
  430. #undef MAKECORNERVERTEX
  431.  
  432.         ++nVertices;
  433.  
  434.         /*Advance to next ball*/
  435.         for (whichDim = 0; whichDim < nTraversalDims; ++whichDim)
  436.         {
  437.         if (traversalDims[whichDim] > 0)
  438.         {
  439.             if ((++index[whichDim]) >= traversalDims[whichDim])
  440.             {
  441.             index[whichDim] = 0;
  442.             }
  443.             else
  444.             {
  445.             break;
  446.             }
  447.         }
  448.         }
  449.     } while (whichDim < nTraversalDims); /*Break is based on advance*/
  450.     
  451.     if (style & BS_JACKS)
  452.     {
  453.         /*Make a jack*/
  454.         /*DIKEO do something about line width*/
  455.         for (k = 0; k < nVertices; ++k)
  456.         {
  457.         AppendSPolylineToPicture(surface, 1, 0, 2, &(faceVertices[k][0]));
  458.         AppendSPolylineToPicture(surface, 1, 0, 2, &(faceVertices[k][2]));
  459.         AppendSPolylineToPicture(surface, 1, 0, 2, &(faceVertices[k][4]));
  460.         }
  461.     }
  462.  
  463. #undef MAKETRI
  464. #define MAKETRI(a, b, c)            \
  465.     v[0] = faceVertices[k][a];        \
  466.     v[1] = faceVertices[k][b];        \
  467.     v[2] = faceVertices[k][c];        \
  468.         AppendSPolyToPolys(polys, 3, v);
  469.  
  470.     if (style & BS_OCTOHEDRA)
  471.     {
  472.         /*Make some octohedra*/
  473.         PolysPtr polys;
  474.         VertexPtr v[3];        /*Vertices of triangles*/
  475.  
  476.         for (k = 0; k < nVertices; ++k)
  477.         {
  478.         polys = AppendPolysToPicture(surface);
  479.         polys -> enclosed = true;
  480.     
  481.         MAKETRI(0, 5, 3);
  482.         MAKETRI(3, 5, 1);
  483.         MAKETRI(1, 5, 2);
  484.         MAKETRI(2, 5, 0);
  485.         MAKETRI(0, 4, 2);
  486.         MAKETRI(2, 4, 1);
  487.         MAKETRI(1, 4, 3);
  488.         MAKETRI(3, 4, 0);
  489.         }
  490.     }
  491. #undef MAKETRI
  492.  
  493.     if (style & BS_CUBES)
  494.     {
  495.         /*Make some cubes*/
  496.         PolysPtr polys;
  497.         VertexPtr v[4];        /*Vertices of triangles*/
  498.  
  499.         for (k = 0; k < nVertices; ++k)
  500.         {
  501.         polys = AppendPolysToPicture(surface);
  502.         /*DIKEO not quite right*/
  503.  
  504.         v[0] = cornerVertices[k][0][0][0];
  505.         v[1] = cornerVertices[k][1][0][0];
  506.         v[2] = cornerVertices[k][1][1][0];
  507.         v[3] = cornerVertices[k][0][1][0];
  508.         AppendSPolyToPolys(polys, 4, v);
  509.  
  510.         v[0] = cornerVertices[k][0][0][1];
  511.         v[1] = cornerVertices[k][0][1][1];
  512.         v[2] = cornerVertices[k][1][1][1];
  513.         v[3] = cornerVertices[k][1][0][1];
  514.         AppendSPolyToPolys(polys, 4, v);
  515.  
  516.         v[0] = cornerVertices[k][0][0][0];
  517.         v[1] = cornerVertices[k][0][0][1];
  518.         v[2] = cornerVertices[k][1][0][1];
  519.         v[3] = cornerVertices[k][1][0][0];
  520.         AppendSPolyToPolys(polys, 4, v);
  521.  
  522.         v[0] = cornerVertices[k][0][1][0];
  523.         v[1] = cornerVertices[k][1][1][0];
  524.         v[2] = cornerVertices[k][1][1][1];
  525.         v[3] = cornerVertices[k][0][1][1];
  526.         AppendSPolyToPolys(polys, 4, v);
  527.  
  528.         v[0] = cornerVertices[k][0][0][0];
  529.         v[1] = cornerVertices[k][0][0][1];
  530.         v[2] = cornerVertices[k][0][1][1];
  531.         v[3] = cornerVertices[k][0][1][0];
  532.         AppendSPolyToPolys(polys, 4, v);
  533.  
  534.         v[0] = cornerVertices[k][1][0][0];
  535.         v[1] = cornerVertices[k][1][1][0];
  536.         v[2] = cornerVertices[k][1][1][1];
  537.         v[3] = cornerVertices[k][1][0][1];
  538.         AppendSPolyToPolys(polys, 4, v);
  539.  
  540.         }
  541.     }
  542.  
  543.     SetVar(surface, MAINDATASET, ballsData);
  544.  
  545.     /*Free up temporary storage*/
  546.     SAFEFREE(traversalDims);
  547.     SAFEFREE(index);
  548.     SAFEFREE(centerVertices);
  549.     SAFEFREE(faceVertices);
  550.     SAFEFREE(cornerVertices);
  551.     }
  552.  
  553.     SetVar(balls, SURFACE, surface);
  554.     SetVar(surface, REPOBJ, balls);
  555.     return ObjTrue;
  556. }
  557.  
  558. static ObjPtr BallsInit(balls)
  559. ObjPtr balls;
  560. /*Initializes a balls object*/
  561. {
  562.     ObjPtr colorObj;
  563.     ObjPtr ballsField;
  564.     ObjPtr sizeObj;
  565.  
  566.     MakeVar(balls, MAINDATASET);
  567.     SetVar(balls, COLOROBJ, colorObj = GetVar(balls, MAINDATASET));
  568.  
  569.     if (colorObj)
  570.     {
  571.     ObjPtr mainDataset;
  572.     SetVar(balls, COLORS, ObjTrue);
  573.  
  574.     /*See if there is a size object*/
  575.         while (mainDataset = GetVar(colorObj, MAINDATASET))
  576.     {
  577.         colorObj = mainDataset;
  578.     }
  579.     sizeObj = GetVar(colorObj, SIZEOBJ);
  580.     if (sizeObj)
  581.     {
  582.         SetVar(balls, SIZEOBJ, sizeObj);
  583.         SetVar(balls, SIZESWITCH, NewInt(1));
  584.     }
  585.     }
  586.  
  587.     return ObjTrue;
  588. }
  589.  
  590. static ObjPtr SetBallsMainDataset(visObj, dataSet)
  591. ObjPtr visObj, dataSet;
  592. /*Sets the main data set of visObj to dataSet*/
  593. {
  594.     SetVar(visObj, MAINDATASET, dataSet);
  595.     return ObjTrue;
  596. }
  597.  
  598. void InitBalls()
  599. /*Initializes balls visualization object*/
  600. {
  601.     ObjPtr icon;
  602.  
  603.     /*Class for a ball cloud*/
  604.     visBalls = NewObject(visSized, 0);
  605.     AddToReferenceList(visBalls);
  606.     SetVar(visBalls, NAME, NewString("Balls"));
  607.     SetVar(visBalls, POINTSTYLE, NewInt(BS_OCTOHEDRA));
  608.     SetMethod(visBalls, INITIALIZE, BallsInit);
  609.     SetVar(visBalls, SIZEOFFSET, NewReal(0.0));
  610.     SetVar(visBalls, SIZEFACTOR, NewReal(1.0));
  611.     SetVar(visBalls, SIZECONSTANT, NewReal(1.0));
  612.     SetVar(visBalls, DEFAULTICON, icon = NewObject(visIcon, 0));
  613.     SetVar(icon, WHICHICON, NewInt(ICONBALLS));
  614.     SetVar(icon, NAME, NewString("Balls"));
  615.     SetVar(icon, HELPSTRING,
  616.     NewString("This icon represents a ball cloud or ball display object.  \
  617. This object can show a ball cloud or group of balls for just about any data field."));
  618.     DeclareIndirectDependency(visBalls, SURFACE, MAINDATASET, DATA);
  619.     DeclareIndirectDependency(visBalls, SURFACE, MAINDATASET, CHANGED);
  620.     DeclareIndirectDependency(visBalls, SURFACE, MAINDATASET);
  621.     DeclareDependency(visBalls, SURFACE, POINTSTYLE);
  622.     SetMethod(visBalls, SURFACE, MakeBallsSurface);
  623.  
  624.     SetMethod(visBalls, SETMAINDATASET, SetBallsMainDataset);
  625.     SetVar(visBalls, STYLE, NewInt(0));
  626.  
  627.     SetMethod(visBalls, ADDCONTROLS, AddBallsControls);
  628.     icon = NewIcon(0, 0, ICONBALLS, "Balls");
  629.     SetVar(icon, HELPSTRING,
  630.     NewString("Click on this icon to see a panel of controls for the ball object."));
  631.     SetVar(visBalls, CONTROLICON, icon);
  632.  
  633.     DefineVisMapping(DS_HASFORM | DS_HASFIELD | DS_VECTOR, -1, -1, -1, visBalls);
  634.     DefineVisMapping(DS_HASFORM | DS_HASFIELD, -1, -1, -1, visBalls);
  635.     DefineVisMapping(DS_HASFORM | DS_HASFIELD | DS_VECTOR | DS_UNSTRUCTURED, -1, -1, -1, visBalls);
  636.     DefineVisMapping(DS_HASFORM | DS_HASFIELD | DS_UNSTRUCTURED, -1, -1, -1, visBalls);
  637. }
  638.  
  639. void KillBalls()
  640. /*Kills balls visualization*/
  641. {
  642.     DeleteThing(visBalls);
  643. }
  644.